package com.rit.secs;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.regex.PatternSyntaxException;

import org.apache.commons.codec.binary.Base64;

import Messages.C2DMRegistration;
import Messages.DoorCommand;
import Messages.InvalidVarListException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.sqs.AmazonSQSAsyncClient;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
import com.amazonaws.services.sqs.model.ListQueuesResult;
import com.amazonaws.services.sqs.model.SendMessageRequest;

public abstract class ServerComm {

	// Global Variables
	private static final String AMAZON_ACCESS_KEY = "AKIAJKMUH3H7DLJTOMSQ";
    private static final String AMAZON_SECRET_KEY = "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";
    
    
    private static final String GRANT_ACCESS = "grantAccess";
    private static final String DENY_ACCESS = "denyAccess";
    
    private static BasicAWSCredentials amazonCreds = new BasicAWSCredentials(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY);
    private static AmazonSQSAsyncClient sqsClient = new AmazonSQSAsyncClient(amazonCreds);
    
    private static String registrationID;
    // TODO: the queueName will be hard-coded. This is required for C2DM registration
    // The queueURL should be searched for during every alert from the Gumstix
    private static String queueName = "myqueue";
    private static String cameraIP = null;
    private static String cameraPort = null;
    //private static String queueURL = null;
    
	
	/**
	 * Sets the name of the Amazon SQS queue, NOT the full name
	 * 
	 * @param newName The new queue name.
	 */
	public static void setQueueName(String newName) {
		queueName = newName;
	}
	
	/**
	 * Returns the Amazon SQS queue name
	 * 
	 * @return The Amazon SQS queue name
	 */
	public static String getQueueName() {
		return queueName;
	}
	
	/**
	 * Sets the registration ID
	 * 
	 * @param newReg The new registration ID
	 */
	public static void setRegistrationID(String newReg) {
		registrationID = newReg;
	}
	
	/**
	 * Returns the C2DM registration ID
	 * 
	 * @return The registration ID
	 */
	public static String getRegistrationID() {
		return registrationID;
	}
	
	/**
	 * Sets the camera IP for the URL
	 * 
	 * @param new_ip The new camera IP
	 */
	public static void setCameraIP(String new_ip) {
		cameraIP = new_ip;
	}
	
	/**
	 * Returns the camera IP in string format
	 * 
	 * @return the camera IP
	 */
	public static String getCameraIP() {
		return cameraIP;
	}
	
	/** 
	 * Sets a new camera port for the URL
	 * 
	 * @param new_port The new camera port
	 */
	public static void setCameraPort(String new_port) {
		cameraPort = new_port;
	}
	
	/**
	 * Returns the camera's port
	 * 
	 * @return The camera port number
	 */
	public static String getCameraPort() {
		return cameraPort;
	}
	
	/**
	 * Search for the queueURL
	 */
	@SuppressWarnings("unchecked")
	public static String findQueueURL() {
		String queueURL = null;
		int i = 0;
		
        ListQueuesResult res = sqsClient.listQueues();
        List<String> temp = (res.getQueueUrls());
        String matchMe = (".*"+queueName+"$");
       
        while(queueURL == null && i < temp.size()) {
        	System.out.println("i = " + i + ": " + temp.get(i));
        	System.out.println("Does it match? " + temp.get(i).matches(matchMe));
        	if(temp.get(i).matches(matchMe)) {
        		queueURL = temp.get(i);
        	}
        	i++;
        }		
		
		return queueURL;
	}
	
	/**
	 * Sends a "DENY_ACCESS" message to the Amazon SQS server
	 */
	public static void denyAccess() {
		
		String queueURL = findQueueURL();
		if(queueURL == null) {
			queueURL = (sqsClient.createQueue(new CreateQueueRequest(queueName))).getQueueUrl();
		}
		DoorCommand doorCmd = new DoorCommand("0", DENY_ACCESS);
		String encodedMessage = new String(Base64.encodeBase64((doorCmd.RenderMessage()).getBytes()));
		System.out.println("denyAccess queueURL = " + queueURL);
	    sqsClient.sendMessage(new SendMessageRequest(queueURL, encodedMessage));
	}
	
	/**
	 * Send a "GRANT_ACCESS" message to the Amazon SQS server
	 */
	public static void grantAccess() {
		
		String queueURL = findQueueURL();
		if(queueURL == null) {
			queueURL = (sqsClient.createQueue(new CreateQueueRequest(queueName))).getQueueUrl();
		}
		DoorCommand doorCmd = new DoorCommand("1", GRANT_ACCESS);
		System.out.println("grantAccess queueURL = " + queueURL);
		String encodedMessage = new String(Base64.encodeBase64((doorCmd.RenderMessage()).getBytes()));
	    sqsClient.sendMessage(new SendMessageRequest(queueURL, encodedMessage));
	    
	}
	
	/**
	 * Returns a "GRANT_ACCESS" message, used for Bluetooth
	 */
	public static String grantViaBluetooth() {
		DoorCommand doorCmd = new DoorCommand("1", GRANT_ACCESS);
		return doorCmd.RenderMessage();
	}
	
	
	/**
	 * sendRegistrationIdToSQS() - Sends the registration ID to AmazonSQS. The microcontroller
	 * will continuously poll AmazonSQS for the registration key. This key is needed for the
	 * microcontroller to send messages to the Android device via C2DM.
	 * 
	 * @return True if the registration was successfully sent to AmazonSQS, otherwise false.
	 */
	public static void sendRegistrationIdToSQS() {
		System.out.println("Inside sendRegistrationIdTOSQS");
		try {    
			String queueURL = findQueueURL();
			// Create a new queue if the pre-determined one does not exist.
			if(queueURL == null) {
				queueURL = (sqsClient.createQueue(new CreateQueueRequest(queueName))).getQueueUrl();
			}
			
	        C2DMRegistration c2dmReg = new C2DMRegistration(registrationID);
	        
	        String encodedMessage = new String(Base64.encodeBase64((c2dmReg.RenderMessage()).getBytes()));
	        sqsClient.sendMessage(new SendMessageRequest(queueURL, encodedMessage)); 
		} catch ( PatternSyntaxException e) {
			e.printStackTrace();
		} catch ( InvalidVarListException e ) {
			e.printStackTrace();
		}
	}
	
	public static Bitmap loadImageFromCamera() {
		
		if(cameraIP == null || cameraPort == null) {
			System.out.println("cameraIP or cameraPort = null");
			return null;
		}
    	try {
    		String credentials = android.util.Base64.encodeToString("admin:secs".getBytes(), android.util.Base64.DEFAULT);
			//URL myFileUrl = new URL("http://129.21.27.69:81/image/jpeg.cgi");
    		URL myFileUrl = new URL("http://" + cameraIP + ":" + cameraPort + "/image/jpeg.cgi" );
			HttpURLConnection camConnection = (HttpURLConnection)myFileUrl.openConnection();
			camConnection.setRequestProperty("Authorization", "Basic " + credentials);
			camConnection.connect();
			Bitmap bmp = BitmapFactory.decodeStream(camConnection.getInputStream());
			//System.out.println("Returning the image");
			return bmp;
    	} catch(MalformedURLException e) {
    		e.printStackTrace();
    	} catch(IOException e) {
    		e.printStackTrace();
    	}catch (Exception e) {
    		e.printStackTrace();
    	}
    	//System.out.println("Returning null for bitmap..");
    	return null;
    }
	
	
}
